<template>
  <!-- 天地图添加热力图 -->
  <div class="box">
    <el-button type="primary" @click="openHeatmap">显示热图</el-button>
    <el-button :plain="true" @click="closeHeatmap">关闭热图</el-button>

    <div class="controls mt-4" v-if="isShowBtn">
      <el-form label-width="120px">
        <el-form-item label="热力图半径">
          <el-slider
            v-model="heatmapRadius"
            :min="5"
            :max="100"
            @change="debounceUpdateHeatmapOptions"
          >
            <template #tooltip="{ value }">半径: {{ value }}</template>
          </el-slider>
        </el-form-item>

        <el-form-item label="热力图透明度">
          <el-slider
            v-model="heatmapOpacity"
            :min="0.1"
            :max="1"
            :step="0.1"
            @change="debounceUpdateHeatmapOptions"
          >
            <template #tooltip="{ value }">透明度: {{ value }}</template>
          </el-slider>
        </el-form-item>

        <el-form-item label="颜色渐变">
          <el-radio-group
            v-model="gradientType"
            @change="debounceUpdateHeatmapOptions"
          >
            <el-radio-button label="default">默认渐变</el-radio-button>
            <el-radio-button label="blue">蓝色系</el-radio-button>
            <el-radio-button label="red">红色系</el-radio-button>
            <el-radio-button label="rainbow">彩虹色</el-radio-button>
          </el-radio-group>
        </el-form-item>
      </el-form>
    </div>
  </div>
  <div id="mapContain" class="map-container"></div>
</template>

<script setup lang="ts">
import { onMounted, ref, nextTick, watchEffect } from 'vue'
//   import { debounce } from '@vueuse/core'
import 'element-plus/dist/index.css'
interface GradientPreset {
  [key: string]: {
    [key: number]: string
  }
}

let isShowBtn = ref(false)
let map: any = null
let heatmapOverlay: any = null
let pointsArr = ref<any[]>([])
let dataLoaded = ref(false)
let isHeatmapShown = ref(false)
let heatmapDataReady = ref(false)
let isUpdating = ref(false)

// 热力图配置
let heatmapRadius = ref(30)
let heatmapOpacity = ref(0.8)
let gradientType = ref('default')

// 预定义的渐变方案
const gradientPresets: GradientPreset = {
  default: {
    0.4: 'blue',
    0.65: 'lime',
    0.8: 'yellow',
    1: 'red',
  },
  blue: {
    0.2: 'rgb(0,0,255)',
    0.4: 'rgb(0,128,255)',
    0.6: 'rgb(0,255,255)',
    0.8: 'rgb(128,255,128)',
    1: 'rgb(255,255,0)',
  },
  red: {
    0.2: 'rgb(255,255,200)',
    0.4: 'rgb(255,220,160)',
    0.6: 'rgb(255,180,120)',
    0.8: 'rgb(255,120,80)',
    1: 'rgb(255,0,0)',
  },
  rainbow: {
    0.1: 'rgba(0, 255, 255, 0.7)',
    0.25: 'rgba(0, 191, 255, 0.7)',
    0.4: 'rgba(0, 0, 255, 0.7)',
    0.55: 'rgba(0, 255, 0, 0.7)',
    0.7: 'rgba(255, 255, 0, 0.7)',
    0.85: 'rgba(255, 127, 0, 0.7)',
    1: 'rgba(255, 0, 0, 0.7)',
  },
}

// 自定义debounce函数（如果未使用@vueuse/core）
const debounce = (fn: Function, wait: number) => {
  let timeout: ReturnType<typeof setTimeout> | null = null
  return function (...args: any[]) {
    if (timeout) clearTimeout(timeout)
    timeout = setTimeout(() => {
      fn.apply(args)
    }, wait)
  }
}

onMounted(() => {
  nextTick(() => {
    initMap()
    loadHeatmapData()
  })
})

const initMap = () => {
  //const T = (window as any).T; // 从window对象获取T命名空间
  map = new T.Map('mapContain')
  map.centerAndZoom(new T.LngLat(108.95, 34.27), 4)
  map.enableScrollWheelZoom()

  // 初始化热力图覆盖层
  heatmapOverlay = new T.HeatmapOverlay({
    radius: heatmapRadius.value,
    opacity: heatmapOpacity.value,
    gradient: gradientPresets[gradientType.value],
  })

  map.addOverLay(heatmapOverlay)

  // 解决Canvas性能警告的关键代码
  // 这里假设天地图热力图插件的Canvas元素可以通过overlay._canvas访问
  // 如果实际属性名不同，需要调整
  if (heatmapOverlay && heatmapOverlay._canvas) {
    heatmapOverlay._canvas.willReadFrequently = true
    console.log('已设置Canvas的willReadFrequently属性为true')
  }

  // 监听数据加载状态
  watchEffect(() => {
    if (
      dataLoaded.value &&
      pointsArr.value.length > 0 &&
      !heatmapDataReady.value
    ) {
      setupHeatmapData()
    }
  })
}

const loadHeatmapData = async () => {
  try {
    const response = await fetch('/public/heatMapData/heatMapData.json')
    const result = await response.json()

    pointsArr.value = result.citydata
      .map((item: any) => {
        const coordinates = result.geoCoordMap[item.name]
        if (coordinates) {
          return {
            name: item.name,
            lat: coordinates[1],
            lng: coordinates[0],
            count: item.value,
          }
        }
        return null
      })
      .filter((point: any) => point !== null)

    console.log('热力图数据加载完成', pointsArr.value)
    dataLoaded.value = true
  } catch (error) {
    console.error('加载热力图数据失败:', error)
    alert('加载热力图数据失败，请检查网络连接')
  }
}

const setupHeatmapData = () => {
  if (heatmapOverlay && pointsArr.value.length > 0) {
    //   const heatmapData = pointsArr.value.map(point => ({
    //     geometry: {
    //       type: 'Point',
    //       coordinates: [point.lng, point.lat],
    //     },
    //     weight: point.count || 1,
    //   }))

    heatmapOverlay.setDataSet({
      data: pointsArr.value,
      max: 300,
    })

    heatmapDataReady.value = true
    console.log('热力图数据已设置')

    // 如果热力图应该显示，则显示
    if (isHeatmapShown.value) {
      heatmapOverlay.show()
    }
  }
}

// 优化的配置更新方法，使用防抖和过渡效果
const updateHeatmapOptions = () => {
  if (!heatmapOverlay || !heatmapDataReady.value || isUpdating.value) return

  isUpdating.value = true

  // 保存当前透明度值
  const currentOpacity = heatmapOpacity.value

  // 临时提高透明度，减少闪烁感
  if (currentOpacity < 0.5) {
    heatmapOverlay.setOptions({ opacity: 0.5 })
  }

  // 延迟更新，让用户界面有时间响应
  setTimeout(() => {
    // 更新热力图配置
    heatmapOverlay.setOptions({
      radius: heatmapRadius.value,
      opacity: currentOpacity, // 恢复原始透明度
      gradient: gradientPresets[gradientType.value],
    })

    console.log(
      `热力图配置已更新: 半径=${heatmapRadius.value}, 透明度=${heatmapOpacity.value}, 渐变=${gradientType.value}`,
    )

    // 确保热力图是显示状态
    if (isHeatmapShown.value) {
      heatmapOverlay.show()
    }

    // 更新完成
    isUpdating.value = false
  }, 100) // 100ms的延迟通常足以让UI更新
}

// 使用防抖处理，避免频繁更新 (300ms防抖)
const debounceUpdateHeatmapOptions = debounce(updateHeatmapOptions, 300)

// 打开热力图
const openHeatmap = () => {
  if (heatmapOverlay && map) {
    isHeatmapShown.value = true
    isShowBtn.value = true

    if (heatmapDataReady.value) {
      heatmapOverlay.show()
      console.log('热力图已显示')
    } else {
      console.log('热力图数据未准备好，等待数据加载...')
      watchEffect((onInvalidate) => {
        if (heatmapDataReady.value) {
          heatmapOverlay.show()
          console.log('热力图数据加载后已显示')
          onInvalidate(() => {})
        }
      })
    }
  }
}

// 关闭热力图
const closeHeatmap = () => {
  if (heatmapOverlay && map) {
    heatmapOverlay.hide()
    isHeatmapShown.value = false
    isShowBtn.value = false
    console.log('热力图已隐藏')
  }
}
</script>

<style lang="scss" scoped>
.box {
  position: fixed;
  top: 5px;
  left: 5px;
  z-index: 1000;
  width: 400px;
  background-color: rgba(255, 255, 255, 0.9);
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.controls {
  margin-top: 15px;
}

.map-container {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0px;
  left: 0;
  z-index: 100;
}

.mt-4 {
  margin-top: 1rem;
}
</style>
